// b10.v
// Verilog version, rewritten by Li Shen, Aug 2002
// Institute of Computing Technology, Chinese Academy of Sciences
// The original VHDL version is b10.vhd from Politecnico di Torino

module b10 (clock,reset,start,r_button,g_button,key,test,rts,rtr,v_in,
             cts,ctr,v_out);
input clock;
input reset;
input start;
input r_button;
input g_button;
input key;
input test;
input rts;
input rtr;
input [3:0] v_in;
output cts;
output ctr;
output [3:0] v_out;
/////
wire clock;
wire reset;
wire start;
wire r_button;
wire g_button;
wire key;
wire test;
wire rts;
wire rtr;
wire [3:0] v_in;
reg cts;
reg ctr;
reg [3:0] v_out;
/////
parameter STARTUP=0, STANDBY=1, GET_IN=2, START_TX=3, SEND=4, TX_2_RX=5;
parameter RECEIVE=6, RX_2_TX=7, END_TX=8, TEST_1=9, TEST_2=10;

reg [3:0] stato;
reg [3:0] sign;
reg voto0,voto1,voto2,voto3,last_g,last_r;

/////

always @(posedge clock)
begin
  if (reset)
  begin
    stato = STARTUP;
    voto0 = 0;
    voto1 = 0;
    voto2 = 0;
    voto3 = 0;
    sign = 4'b0000;
    last_g = 0;
    last_r = 0;
    cts <= 0;
    ctr <= 0;
    v_out <= 4'b0000;
  end
  else
  case (stato)

  STARTUP:
  begin
	voto0 = 0;
	voto1 = 0;
	voto2 = 0;
	voto3 = 0;
	cts   <= 0;
	ctr   <= 0;
	if (!test)
	begin
	  sign  = 4'b0000;
	  stato = TEST_1;
	end
	else
	begin
	  voto0 = 0;
	  voto1 = 0;
	  voto2 = 0;
	  voto3 = 0;
	  stato = STANDBY ;
	end
  end

  STANDBY:
  begin
    if (start)
    begin
	voto0 = 0;
	voto1 = 0;
	voto2 = 0;
	voto3 = 0;
	stato = GET_IN;
    end
    if (rtr)  cts <= 1;
    if (!rtr) cts <= 0;
  end

  GET_IN:
  begin
    if (!start)
	stato = START_TX;
    else if (key)
	 begin
	   voto0 = key ;
	   if (( g_button ^ last_g ) & g_button)
		voto1 = ~voto1 ;
	   if (( r_button ^ last_r ) & r_button)
		voto2 = ~voto2 ;
	   last_g = g_button ;
	   last_r = r_button ;
	 end
    else
    begin
	voto0 = 0;
	voto1 = 0;
	voto2 = 0;
	voto3 = 0;
    end
  end

  START_TX:
  begin
	voto3 = voto0 ^ voto1 ^ voto2;
	stato = SEND;
	voto0 = 0;
  end

  SEND:
    if (rtr)
    begin
	v_out[0] <= voto0 ;
	v_out[1] <= voto1 ;
	v_out[2] <= voto2 ;
	v_out[3] <= voto3 ;
	cts <= 1;
	if (!voto0 && voto1 && voto2 && !voto3)
	  stato = END_TX ;
	else
	  stato = TX_2_RX ;
    end

  TX_2_RX:
    if (!rts)
    begin
	ctr <= 1;
	stato = RECEIVE ;
    end

  RECEIVE:
    if (rts)
    begin
	voto0 = v_in[0] ;
	voto1 = v_in[1] ;
	voto2 = v_in[2] ;
	voto3 = v_in[3] ;
	ctr <= 0 ;
	stato = RX_2_TX ;
    end

  RX_2_TX:
    if (!rtr)
    begin
	cts <= 0 ;
	stato = SEND ;
    end

  END_TX:
    if (!rtr)
    begin
	cts <= 0 ;
        stato = STANDBY ;
    end

  TEST_1:
    begin
 	voto0 = v_in[0] ;
	voto1 = v_in[1] ;
	voto2 = v_in[2] ;
	voto3 = v_in[3] ;
	sign = 4'b1000;
	if (voto0 && voto1 && voto2 && voto3)
	  stato = TEST_2 ;
    end

  TEST_2:
  begin
 	voto0 = 1 ^ sign[0] ;
	voto0 = 0 ^ sign[1] ;
	voto0 = 0 ^ sign[2] ;
	voto0 = 1 ^ sign[3] ;
	stato = SEND ;
  end
  endcase
end
endmodule
